This page last changed on Feb 27, 2007 by cholmes.

Introduction

In the GeoServer community we've been really enjoying MetaCarta's TileCache as a caching layer in front of the WMS. You can see it in action at http://sigma.openplans.org. If you have non-dynamic mapping data in GeoServer using it will help give your users an experience that comes close to matching Google Maps in terms of responsiveness and usability. This tutorial will take you through setting it up (mostly pointing at their docs) as well as some hints and tricks that we've come upon in working with it. If you have information we've missed her don't hesitate to include it, this is a wiki, just hit 'page operations -> edit page' on the left. We're currently recommending this solution over squid or oscache, as TileCache was specially designed for WMS.

Background

TileCache comes out of some great discussions the Open Source Geospatial community had at the FOSS4G 2006 conference. The goal was to come up with standardized ways to request WMS images, in order to increase their ability to be cached. This enables clients to work against 'tiles' which they can request in a batch, and which need only be created once, instead of making a dynamic request for every image. This was one of the nice (re)-innovations of Google Maps, and we figured we could leverage our existing Web Map Service implementations to do the image generation, by having clients agree on the way to ask for images.

The result of this was two testing specifications, which we hope will get wider adoption and eventually turned in to more official specs. The WMS Tiling Client Recommendation specifies how a normal WMS client can make requests in such a way that WMS servers will be able to take advantage of caching. And the Tile Map Service Specification is an attempt at a new service specifically aimed at serving tiles (though potentially backed by a traditional WMS).

TileCache implements both specs, in the latter case by only allowing properly formed WMS requests through, and caching the results. It is developed in python, and sits in front of any WMS. It works in conjunction with a tiling client like OpenLayers, and indeed was developed by the same people.

Installation

Setting up TileCache is a breeze. From their homepage

This will just cache MetaCarta's vmap0 layer on the temp directory of your disk, but you probably want it caching your GeoServer instance

Configuration

TileCache's configuration is done in the tilecache.cfg file. The first change you probably want to make is to have it save tiles somewhere other than your temp directory. Change the 'base' property to the location you want to save it, and make sure that TileCache (or apache or whatever is running the CGI) has permissions to write to that location.

Next you'll want to set up TileCache to point at your GeoServer instance. The most basic configuration for this is:

    [sigma]
    type=WMSLayer
    layers=topp:countries,topp:gnis_pop
    url=http://sigma.openplans.org:8080/geoserver/wms?
    extension=png

'sigma' is the name of the layer that TileCache will respond to. You list your layers, this can be many as we do above, or just one. And you put in the url of your GeoServer, and the image extension.

To test this you'll want to use OpenLayers. TileCache's demo uses OpenLayers, so the easiest thing to do to see if your layer is working is to modify the index.html at the root of your tilecache installation. Edit the 'layers: vmap0' from vmap0 to what you named your layer.

Customization

Next you'll want to get your TileCache working with your own web client. Currently OpenLayers is our favorite web client that works against TileCache, but for flash types there is also WorldKit. Setting up a nice OpenLayers map is beyond the scope of this tutorial, but we recommend checking out their examples and borrowing code from there.

To get your new TileCache layer in OpenLayers is very easy though. You just set it as a normal WMS layer, and since OpenLayers follows the WMS Tiling Client recommendation it works out of the box.

ol_map = new OpenLayers.Map('ol_map', {'controls': [], 'maxZoomLevel': 17} );
  wms_sigma = new OpenLayers.Layer.WMS( "TIGER", "http://sigma.openplans.org/tilecache-1.3/tilecache.py?",
                                      {layers: 'sigma' }, {numZoomLevels: 17});
  ol_map.addLayer(wms_sigma);

Tips and Tricks

In our experiences with TileCache we've got a few recommendations to give more options and have things perform even better. Some of this is in the TileCache docs, but we thought we'd make it a bit more obvious, and combine information from a few sources.

Transparency (and other style and other WMS parameters)

One of the main questions with TileCache is 'how do I make my layers transparent'? This is quite easy to do, after you've been told how.

  url=http://sigma.openplans.org:8080/geoserver/wms?transparent=true

The way that TileCache works is it just uses whatever url you supply as the base url, and tacks on the parameters it needs. The side effect is that you can add on any number of WMS parameters to that base url. You can set alternate 'styles' there, and even supply full SLD parameters. You just have to add the parameters to the 'url' configuration part for your layer.

metaTile

One of the best performance improvements you can do for GeoServer is to turn on 'metaTile'. This also leads to nicer maps in many cases.

  [sigma]
  type=WMSLayer
  layers=topp:poly_landmarks,topp:water_polygon,topp:water_shorelines,topp:roads,topp:major_roads,topp:states,topp:countries,topp:gnis_pop
  url=http://sigma.openplans.org:8080/geoserver/wms?transparent=true
  extension=png
  metaTile=true

Be aware that this option requires you to have the Python Imaging library installed on your python instance. If your TileCache doesn't work when you set metaTile=true then you probably don't have it properly installed.

metaTile asks for a single large tile that TileCache then divides up in to the smaller tiles. In GeoServer we've seen great performance improvements on vector layers when using this - our sigma layer used to take just under a second for each tile, when it was generating each small tile. With metaTile set to true we average 6-7 tiles per second, so at least a 5x speed improvement.

The downside is that it takes longer for the initial request to appear on the screen, since it's generating a chunk of tiles all at once. You can control how many tiles are requested with the metaSize property. It defaults to 5x5. It's worth playing with this setting, the trade off is between how fast the initial tile loads and how fast all the tiles load. If you're seeding the cache it's worthwhile to set it quite large, since overall the bigger the size the faster things will go.

The metaBuffer parameter is not really needed by GeoServer, since it doesn't have trouble with trying to round corners at image borders. But using metaTile does lead to nicer looking images, since labeling is really hard to get right in tiles. We did a good bit of research to try to get things better, but concluded that a metaTile approach is probably the best way to go.

Note that raster layers likely won't see very big performance gains from this, unless the overhead on the WMS of reading the request and accessing the raster each time is high. But we've not tested this extensively, so please report back if you test it out.

mod_python

We highly recommend installing mod_python to run your tilecache. It makes thing significantly faster, and after all, you're doing this to get things fast, so why not go all the way? You'll have to install mod_python in to your apache instance. Then just follow the directions in the TileCache README, it has directions to set up under mod_python. There's little more for us to say, but we just want to emphasize that it's worthwhile to take the time to set it up, it should be at least two times as fast, if not much more.

mod_expires

If you're running apache you should set mod_expires. This gives a more pleasing experience to users, since their clients will cache the images on their computer. If this is not set than panning to a new area an then back will cause a reload on the original area. If you set mod_expires then your browser will know it doesn't need to ask for the images again. Six hours is likely long enough to set, just adjust your apache config (and be sure it's installed).

ExpiresActive on
ExpiresDefault "now plus 6 hours"

Cheat the browser's connection limit with OpenLayers

One of the ways that the Google, Yahoo! and Microsoft get such fast loading maps is that they have your browser open many connections. If you've ever watched closely when Google Maps is loading you've probably seen loading coming from kh1.google.com, kh2.google.com, kh3.google.com, ect. Most browsers only let you open two connections to a server at once.

As of version 2.3 OpenLayers will let you supply a list of WMS names, instead of just one, and it will hit all with tile requests instead of just one.

          wms_sigma = new OpenLayers.Layer.WMS( "TIGER",
              ["http://sigma4.openplans.org/tilecache-1.3/tilecache.py?",
               "http://sigma3.openplans.org/tilecache-1.3/tilecache.py?",
               "http://sigma2.openplans.org/tilecache-1.3/tilecache.py?",
               "http://sigma1.openplans.org/tilecache-1.3/tilecache.py?"],
              {layers: 'sigma' }, {numZoomLevels: 17});

Now you might be thinking 'but I don't have four servers!'. No need to worry, you can get increased performance with just one server. You just have to set up the dns right so that all names point at the same machine (and maybe some configuration of the server, if anyone has advice then just add it (it's a wiki, hit 'page operations -> edit page' on the left). Even if it's all pointing at the same machine things should appear much faster to users, since TileCache is able to return images quite quickly, so if you ask for more at once, it can return more at once.

Seeding the Cache

One the great, little known, tools of TileCache is the client, which lets you automatically 'seed' the cache, generating requests to your GeoServer before real clients hit it. With this you can ensure that every request is fast from the beginning, or even selectively pre-cache certain areas that you want to be sure are fast, and let users iteratively cache popular areas.

Up until version 1.4 there was no documentation on this, and even now it's buried as the last section of the readme.

The client is located in the TileCache subdirectory of the TileCache install. It's a python program that iteratively makes calls to your server and caches them in a given area and zoom level.

python Client.py 'http://monitor.metacarta.com/wms-c/Basic.py?' DRG 0 13 -124.334335,25.569305,-69.051132,49.56344 

This says cache the 'DRG' layer from http://monitor.metacarta.com/wms-c/Basic.py?' at zoom levels 0 to 13 for the United States. You want to aim it at your tilecache instance, all it does is walk the area given, so if you point it straight at GeoServer it won't seed your cache. Adjust it to the layer, area and zoom levels you want to pre-cache.

We like to run this process on our server, so there's no lag because of the network. But this process can take a long time to run, so we recommend using 'nohup' before it if you're telneting in, so that if your connection goes down the process will keep going. For really large maps you likely will want to just pre-cache the first zooms, since it can days, if not weeks or months, to pre-cache all zoom levels. Our sigma cache is currently at over 80 gigabytes.

Note that you can also pass a file of areas to cache in to the client. Unfortunately it only takes a position and a degree size, so you can't get very exact. We'll work to provide one in due time, and if anyone else has one feel free to post it.

Get rid of pink tiles

We've experienced a number of times when not all the tiles of OpenLayers successfully load, often leaving a pink tile instead of your nice map. This seems to happen a bit more with TileCache, it may be due to OpenLayers not quite getting things right for the WMS tiling recommendation. But thankfully there's now a nice configuration option to get around it. It's a bit of a hack, basically it will cause openlayers to not give up right away, but to try the server a few more times. To set it you just set it in your openlayers javascript.

OpenLayers.IMAGE_RELOAD_ATTEMPTS = 3;

This tells it to try to reload 3 times. You can set the number as high or as low as you'd like, but we've found good success with 3.

Document generated by Confluence on Jan 16, 2008 23:28